package com.youlu.campus.activity.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.activity.entity.UserActivityQuantityRecord;
import com.youlu.campus.activity.repositories.UserActivityTaskRankingRepository;
import com.youlu.campus.activity.service.UserActivityQuantityRecordService;
import com.youlu.campus.activity.service.UserActivityTaskRankingService;
import com.youlu.campus.entity.ActivityTaskInfo;
import com.youlu.campus.entity.UniversityInfo;
import com.youlu.campus.entity.UserPO;
import com.youlu.campus.entity.VO.res.ActivityRankingPointsVO;
import com.youlu.campus.entity.enums.TaskBizType;
import com.youlu.campus.service.rank.UserRankListService;
import com.youlu.campus.service.ranking.UserActivityPointRankingProvinceService;
import com.youlu.campus.service.ranking.entity.UserActivityTaskRanking;
import com.youlu.campus.service.ranking.entity.UserActivityTaskRankingQueryVo;
import com.youlu.campus.service.university.UniversityService;
import com.youlu.campus.service.visitor.VisitorUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * 用户 参加活动的 贡献值榜单 服务
 *
 * @Description: UserActivityTaskRankingServiceImpl
 * @Date 2025/8/1
 * @module UserActivityTaskRankingServiceImpl
 * @author: su
 */
@Slf4j
@Service
public class UserActivityTaskRankingServiceImpl implements UserActivityTaskRankingService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private UserActivityTaskRankingRepository repository;

    @Autowired
    private UserActivityQuantityRecordService userActivityQuantityRecordService;

    @Autowired
    private UserRankListService userRankListService;

    @Autowired
    private UserActivityPointRankingProvinceService userActivityPointRankingProvinceService;

    @Autowired
    private VisitorUserService visitorUserService;

    @Autowired
    private UniversityService universityService;

    @Override
    public List<UserActivityTaskRanking> findByActivityId(String activityId) {
        return repository.findByActivityId(activityId);
    }

    @Override
    public UserActivityTaskRanking save(UserActivityTaskRanking userActivityTaskRanking) {
        return repository.save(userActivityTaskRanking);
    }

    @Async
    @Override
    public void updateUser(String activityId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("activityId").is(activityId));
        long count = mongoTemplate.count(query, UserActivityTaskRanking.class);
        log.info("updateUser activityId:{} count:{}", activityId, count);
        if (count == 0) {
            return;
        }
        Date date = new Date();
        long pageNum = count % 1000 == 0 ? count / 1000 : count / 1000 + 1;
        for (int page = 0; page < pageNum; page++) {
            //查询列表
            query.with(PageRequest.of(page, 1000));
            List<UserActivityTaskRanking> listTask = this.mongoTemplate.find(query, UserActivityTaskRanking.class);
            if (CollectionUtils.isEmpty(listTask)) {
                continue;
            }
            for (UserActivityTaskRanking userActivityTaskRanking : listTask) {
                log.info("updateUser activityId:{} userActivityTaskRanking:{}", activityId, JSONObject.toJSONString(userActivityTaskRanking));
                UserPO user = visitorUserService.findUserByUserId(userActivityTaskRanking.getUserId());
                if (Objects.isNull(user)) {
                    continue;
                }
                Query queryUpdate = new Query().addCriteria(Criteria.where("id").is(userActivityTaskRanking.getId()));
                Update update = new Update();
                if (StringUtils.isBlank(user.getUniversityName()) && StringUtils.isNotBlank(user.getUniversityId())) {
                    UniversityInfo universityInfo = universityService.get(user.getUniversityId());
                    if (universityInfo != null) {
                        user.setUniversityName(universityInfo.getName());
                        user.setUniversityLogo(universityInfo.getLogo());
                    }
                }
                if (StringUtils.isNotBlank(user.getUniversityName())) {
                    update.set("universityName", user.getUniversityName());
                }
                if (StringUtils.isNotBlank(user.getUniversityId())) {
                    update.set("universityId", user.getUniversityId());
                }
                if (StringUtils.isNotBlank(user.getUniversityLogo())) {
                    update.set("universityLogo", user.getUniversityLogo());
                }
                if (StringUtils.isNotBlank(user.getNickName())) {
                    update.set("name", user.getNickName());
                }
                if (StringUtils.isNotBlank(user.getName())) {
                    update.set("userName", user.getName());
                }
                if (StringUtils.isNotBlank(user.getMobile())) {
                    update.set("mobile", user.getMobile());
                }
                if (StringUtils.isNotBlank(user.getAvatarUrl())) {
                    update.set("imageUrl", user.getAvatarUrl());
                }
                update.set("updatedTime", date);
                mongoTemplate.updateMulti(queryUpdate, update, UserActivityTaskRanking.class);
            }
        }
    }

    @Override
    public UserActivityTaskRanking saveQuantityByInvited(UserPO user, ActivityTaskInfo taskInfo, UserPO invitedToUser) {
        log.info("saveQuantityByInvited 添加邀请贡献值 userId:{},邀请用户id:{},任务数据:{}", user.getId(), invitedToUser.getId(), JSON.toJSONString(taskInfo));
        try {
            // 计算需要增加的贡献值
            double addQuantity = taskInfo.getPoints();
            if (StringUtils.isNotBlank(user.getUniversityId()) && user.getUniversityId().equals(invitedToUser.getUniversityId())) {
                addQuantity += taskInfo.getExtraPoints();
            }
            UserActivityTaskRanking ranking = findAndModify(user, taskInfo, addQuantity);
            log.info("saveQuantityByInvited ranking:{}", JSONObject.toJSONString(ranking));
            //新增用户 贡献值记录
            UserActivityQuantityRecord userActivityQuantityRecord = new UserActivityQuantityRecord();
            userActivityQuantityRecord.setUserId(ranking.getUserId());
            userActivityQuantityRecord.setActivityId(ranking.getActivityId());
            userActivityQuantityRecord.setActivityTaskInfoId(ranking.getTaskId());
            userActivityQuantityRecord.setTaskBizType(ranking.getTaskBizType());
            userActivityQuantityRecord.setInviteToUserId(invitedToUser.getId());
            userActivityQuantityRecord.setPoints(taskInfo.getPoints());
            userActivityQuantityRecord.setExtraPointsStatus(false);
            //受邀人 学校id 与邀请人学校id 相同 增加 额外工作量
            if (StringUtils.isNotBlank(user.getUniversityId()) && user.getUniversityId().equals(invitedToUser.getUniversityId())) {
                userActivityQuantityRecord.setExtraPoints(taskInfo.getExtraPoints());
            }
            userActivityQuantityRecordService.insert(userActivityQuantityRecord);
            //更新地区榜单
            updateAreaRanking(user, ranking, addQuantity);
            return ranking;
        } catch (Exception e) {
            log.error("error:{}", e.getMessage(), e);
            return null;
        }
    }

    @Override
    public UserActivityTaskRanking saveQuantity(UserPO user, ActivityTaskInfo taskInfo, TaskBizType taskBizType) {
        if (Objects.isNull(user) || Objects.isNull(taskInfo)) {
            log.error("saveQuantity 添加邀请贡献值 参数错误 user:{},taskInfo:{}", user, taskInfo);
            return null;
        }
        log.info("saveQuantity 添加邀请贡献值 userId:{},taskInfo:{},taskBizType:{}", user.getId(), JSON.toJSONString(taskInfo), taskBizType);
        try {
            UserActivityTaskRanking ranking = findAndModify(user, taskInfo, taskInfo.getPoints());
            log.info("saveQuantity ranking:{}", JSONObject.toJSONString(ranking));
            //新增用户 贡献值记录
            UserActivityQuantityRecord userActivityQuantityRecord = new UserActivityQuantityRecord();
            userActivityQuantityRecord.setUserId(ranking.getUserId());
            userActivityQuantityRecord.setActivityId(ranking.getActivityId());
            userActivityQuantityRecord.setActivityTaskInfoId(ranking.getTaskId());
            userActivityQuantityRecord.setTaskBizType(taskBizType);
            userActivityQuantityRecord.setPoints(taskInfo.getPoints());
            userActivityQuantityRecordService.insert(userActivityQuantityRecord);
            //更新地区榜单
            updateAreaRanking(user, ranking, taskInfo.getPoints());
            return ranking;
        } catch (Exception e) {
            log.error("error:{}", e.getMessage(), e);
            return null;

        }
    }

    /**
     * 更新用户参与活动榜单
     *
     * @param user
     * @param taskInfo
     * @param addQuantity
     * @return
     */
    private UserActivityTaskRanking findAndModify(UserPO user, ActivityTaskInfo taskInfo, double addQuantity) {
        Query query = new Query(Criteria.where("userId").is(user.getId()).and("activityId").is(taskInfo.getActivityId()));
        Update update = new Update();
        update.set("activityId", taskInfo.getActivityId());
        update.set("taskId", taskInfo.getId());
        update.set("taskBizType", taskInfo.getTaskBizType());
        update.set("userId", user.getId());
        if (StringUtils.isNotBlank(user.getUniversityName())) {
            update.set("universityName", user.getUniversityName());
        }
        if (StringUtils.isNotBlank(user.getUniversityId())) {
            update.set("universityId", user.getUniversityId());
        }
        if (StringUtils.isNotBlank(user.getUniversityLogo())) {
            update.set("universityLogo", user.getUniversityLogo());
        }
        if (StringUtils.isNotBlank(user.getNickName())) {
            update.set("name", user.getNickName());
        }
        if (StringUtils.isNotBlank(user.getName())) {
            update.set("userName", user.getName());
        }
        if (StringUtils.isNotBlank(user.getMobile())) {
            update.set("mobile", user.getMobile());
        }
        if (StringUtils.isNotBlank(user.getAvatarUrl())) {
            update.set("imageUrl", user.getAvatarUrl());
        }
        // 使用$inc原子操作增加数量（避免并发问题）
        update.inc("quantity", addQuantity);
        Date date = new Date();
        update.setOnInsert("createdTime", date); // 只有插入时才会设置
        update.set("updatedTime", date); // 无论新增还是更新都会设置
        // 配置findAndModify选项
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
        findAndModifyOptions.upsert(Boolean.TRUE);
        findAndModifyOptions.returnNew(Boolean.TRUE);
        // 执行操作并获取结果
        UserActivityTaskRanking ranking = mongoTemplate.findAndModify(query, update, findAndModifyOptions, UserActivityTaskRanking.class);
        log.info("saveQuantity ranking:{}", JSONObject.toJSONString(ranking));
        return ranking;
    }

    @Override
    public Boolean addQuantityByUserIdAndActivityId(String userId, String activityId, Double quantity, TaskBizType taskBizType) {
        log.info("addQuantityByUserIdAndActivityId userId:{},activityId:{},quantity:{},taskBizType:{}", userId, activityId, quantity, taskBizType);
        try {
            Query query = new Query(Criteria.where("userId").is(userId).and("activityId").is(activityId));
            Update update = new Update();
            update.set("updatedTime", new Date()); // 无论新增还是更新都会设置
            update.inc("quantity", quantity);
            // 配置findAndModify选项
            FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
            findAndModifyOptions.upsert(Boolean.TRUE);
            findAndModifyOptions.returnNew(Boolean.TRUE);
            // 执行操作并获取结果
            UserActivityTaskRanking ranking = mongoTemplate.findAndModify(query, update, findAndModifyOptions, UserActivityTaskRanking.class);
            log.info("addQuantityByUserIdAndActivityId ranking:{}", JSONObject.toJSONString(ranking));

            //新增用户 贡献值记录
            UserActivityQuantityRecord userActivityQuantityRecord = new UserActivityQuantityRecord();
            userActivityQuantityRecord.setUserId(ranking.getUserId());
            userActivityQuantityRecord.setActivityId(ranking.getActivityId());
            userActivityQuantityRecord.setActivityTaskInfoId(ranking.getTaskId());
            userActivityQuantityRecord.setTaskBizType(taskBizType);
            userActivityQuantityRecord.setPoints(quantity);
            userActivityQuantityRecordService.insert(userActivityQuantityRecord);

            //更新地区榜单
            updateAreaRanking(null, ranking, quantity);
            return true;
        } catch (Exception e) {
            log.error("error:{}", e.getMessage(), e);
            return null;

        }
    }

    /**
     * 更新地区榜单
     *
     * @param ranking
     * @param addQuantity
     */
    private void updateAreaRanking(UserPO user, UserActivityTaskRanking ranking, Double addQuantity) {
        if (Objects.isNull(user)) {
            user = visitorUserService.getUser(ranking.getUserId());
        }
        //总 贡献值  TODO 获取用户总贡献值 (兼容一个手机号绑定多个账户共享贡献值总和的缺陷)
        Double qAll = getQuantity(ranking.getUserId(), ranking.getActivityId());
        if (ranking.getQuantity() > qAll) {
            log.error("updateAreaRanking 获取贡献值异常重新获取 更新排行榜的 贡献值:{} 总贡献值:{}", ranking.getQuantity(), qAll);
            qAll = getQuantity(ranking.getUserId(), ranking.getActivityId());
        }
        log.info("updateAreaRanking 更新排行榜的 贡献值:{} 总贡献值:{}", ranking.getQuantity(), qAll);
        String activityId = ranking.getActivityId();  //活动id
        String taskId = ranking.getTaskId(); //任务id
        String userId = ranking.getUserId(); //用户id
        String province = ranking.getProvince(); //省
        String universityId = ranking.getUniversityId();  //大学id
        if (StringUtils.isBlank(universityId)) {
            universityId = user.getUniversityId();
        }
        //更新Redis全国 排行榜
        userRankListService.updateRankCountry(activityId, taskId, userId, addQuantity, qAll);
        //获取省  补偿机制 避免省份不在
        if (StringUtils.isBlank(province)) {
            UserActivityTaskRanking userActivityTaskRanking = updateByUniversity(universityId, ranking);
            province = userActivityTaskRanking.getProvince();
        }
        if (StringUtils.isNotBlank(province)) {
            log.info("updateAreaRanking province:{} qAll:{}", province, qAll);
            userRankListService.updateRankProvince(activityId, taskId, userId, province, qAll);
            userActivityPointRankingProvinceService.saveQuantity(user, province, activityId, qAll);
        }
    }

    /**
     * 修改排行榜 学校信息
     *
     * @param ranking
     * @return
     */
    private UserActivityTaskRanking updateByUniversity(String universityId, UserActivityTaskRanking ranking) {
        Query query = new Query(Criteria.where("userId").is(ranking.getUserId()).and("activityId").is(ranking.getActivityId()));
        Update update = new Update();

        UniversityInfo universityInfo = universityService.get(universityId);
        update.set("universityId", universityId);
        if (StringUtils.isNotBlank(universityInfo.getName())) {
            update.set("universityName", universityInfo.getName());
        }
        if (StringUtils.isNotBlank(universityInfo.getLogo())) {
            update.set("universityLogo", universityInfo.getLogo());
        }
        if (StringUtils.isNotBlank(universityInfo.getProvince())) {
            update.set("province", universityInfo.getProvince());
        }
        update.set("updatedTime", new Date()); // 无论新增还是更新都会设置
        // 配置findAndModify选项
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
        findAndModifyOptions.upsert(Boolean.TRUE);
        findAndModifyOptions.returnNew(Boolean.TRUE);
        // 执行操作并获取结果
        ranking = mongoTemplate.findAndModify(query, update, findAndModifyOptions, UserActivityTaskRanking.class);
        log.info("updateByUniversity ranking:{}", JSONObject.toJSONString(ranking));
        return ranking;
    }


    @Override
    public UserActivityTaskRanking findByUserIdAndActivityId(String userId, String activityId) {
        return this.repository.findByUserIdAndActivityId(userId, activityId);
    }

    @Override
    public Long deleteByUserIdAndActivityId(String userId, String activityId) {
        UserActivityTaskRanking taskRanking = this.repository.findByUserIdAndActivityId(userId, activityId);
        if (Objects.isNull(taskRanking)) {
            return 0L;
        }
        Long b = repository.deleteByUserIdAndActivityId(userId, activityId);
        //删除全国 排行榜 缓存
        userRankListService.deleteRankCountry(activityId, taskRanking.getTaskId(), userId);
        //删除 省 排行榜 缓存
        userRankListService.deleteRankProvince(activityId, taskRanking.getTaskId(), userId);
        return b;
    }

    @Override
    public Double getQuantity(String userId, String activityId) {
        /**
         * 获取用户贡献值
         * 1. 原来的逻辑是通过用户id 查询到手机号
         * 2. 然后通过手机号 获取到所有的用户id
         * 3. 兼容老逻辑  慢慢的参与活动 一个手机号只能绑定一个用户  会修复掉
         */
        List<String> correntUserId = visitorUserService.findCorrentUserId(userId);
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").in(correntUserId).and("activityId").is(activityId).and("taskId").ne(null));
        List<UserActivityTaskRanking> userActivityTaskRankings = mongoTemplate.find(query, UserActivityTaskRanking.class);
        if (CollectionUtils.isEmpty(userActivityTaskRankings)) {
            return 0D;
        }
        double quantity = 0D;
        for (UserActivityTaskRanking userActivityTaskRanking : userActivityTaskRankings) {
            log.info("getQuantity 贡献值 userId:{},activityId:{},quantity:{}", userActivityTaskRanking.getUserId(), activityId, userActivityTaskRanking.getQuantity());
            quantity += userActivityTaskRanking.getQuantity();
        }
        return quantity;
    }


    @Override
    public Page<ActivityRankingPointsVO> findByPage(UserActivityTaskRankingQueryVo queryVo) {
        log.info("findByPage queryVo:{}", JSONObject.toJSONString(queryVo));
        String activityId = queryVo.getActivityId();
        Query query = new Query();
        query.addCriteria(Criteria.where("activityId").is(activityId));
        if (StringUtils.isNotBlank(queryVo.getUniversityId())) {
            query.addCriteria(Criteria.where("universityId").is(queryVo.getUniversityId()));
        }
        if (StringUtils.isNotBlank(queryVo.getName())) {
            query.addCriteria(Criteria.where("name").regex(queryVo.getName(), "i"));
        }
        if (StringUtils.isNotBlank(queryVo.getUserName())) {
            query.addCriteria(Criteria.where("userName").regex(queryVo.getUserName(), "i"));
        }
        if (StringUtils.isNotBlank(queryVo.getMobile())) {
            query.addCriteria(Criteria.where("mobile").is(queryVo.getMobile()));
        }
        PageRequest pageRequest = PageRequest.of(queryVo.getPage() - 1, queryVo.getPageSize());
        Long count = this.mongoTemplate.count(query, UserActivityTaskRanking.class);
        if (count == 0) {
            return PageableExecutionUtils.getPage(new ArrayList<>(), pageRequest, () -> count);
        }
        //计数
        AtomicReference<Integer> rankNo = new AtomicReference<>((queryVo.getPage() - 1) * queryVo.getPageSize() + 1);
        //查询列表
        query.with(Sort.by(Sort.Direction.DESC, "quantity"));
        query.with(PageRequest.of(queryVo.getPage() - 1, queryVo.getPageSize()));
        List<UserActivityTaskRanking> listTask = this.mongoTemplate.find(query, UserActivityTaskRanking.class);
        List<ActivityRankingPointsVO> listRanking = listTask.stream().map(taskRanking -> {
            Integer rankNumber = rankNo.get();
            ActivityRankingPointsVO pointsVO = new ActivityRankingPointsVO();
            pointsVO.setUserId(taskRanking.getUserId());
            pointsVO.setUniversityId(taskRanking.getUniversityId());
            pointsVO.setProvince(taskRanking.getProvince());
            pointsVO.setRankNo(rankNumber);
            pointsVO.setAvatarUrl(taskRanking.getImageUrl());
            pointsVO.setNickName(taskRanking.getName());
            pointsVO.setName(taskRanking.getUserName());
            pointsVO.setUniversityName(taskRanking.getUniversityName());
            pointsVO.setMobile(taskRanking.getMobile());
            pointsVO.setPoints(taskRanking.getQuantity());
            pointsVO.setTenantId(taskRanking.getTenantId());
            pointsVO.setActivityId(taskRanking.getActivityId());
            rankNo.getAndSet(rankNumber + 1);
            return pointsVO;
        }).collect(Collectors.toList());
        return PageableExecutionUtils.getPage(listRanking, pageRequest, () -> count);
    }

    @Override
    public Long count(Query query) {
        Long count = this.mongoTemplate.count(query, UserActivityTaskRanking.class);


        return count;
    }

    @Override
    public Long countByActivityIdAndTaskId(String activityId, String taskId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("activityId").is(activityId).and("taskId").is(taskId));
        Long count = mongoTemplate.count(query, UserActivityTaskRanking.class);
        return count;
    }

    @Override
    public List<UserActivityTaskRanking> find(Query query) {
        List<UserActivityTaskRanking> listTask = this.mongoTemplate.find(query, UserActivityTaskRanking.class);
        return listTask;
    }


    @Override
    public List<UserActivityTaskRanking> findByActivityIdAndTaskId(String activityId, String taskId) {
        log.info("findByActivityIdAndTaskId 活动ID:{},任务ID:{}", activityId, taskId);
        Query query = new Query();
        query.addCriteria(Criteria.where("activityId").is(activityId).and("taskId").is(taskId));
        Sort sortAll = Sort.by(Sort.Direction.DESC, "quantity");
        query.with(sortAll);
        query.limit(1000);
        List<UserActivityTaskRanking> rankings = mongoTemplate.find(query, UserActivityTaskRanking.class);
        return rankings;
    }

    @Override
    public UserActivityTaskRanking findByActivityIdAndTaskIdAndUserId(String activityId, String taskId, String userId) {
        Query queryRank = new Query().addCriteria(Criteria.where("userId").is(userId).and("taskId").is(taskId).and("activityId").is(activityId));
        UserActivityTaskRanking userActivityTaskRanking = mongoTemplate.findOne(queryRank, UserActivityTaskRanking.class);
        return userActivityTaskRanking;
    }

    @Override
    public List<UserActivityTaskRanking> findByActivityIdAndTaskIdAndUserIdIn(String activityId, String taskId, List<String> userIds) {
        Query queryU = new Query();
        queryU.addCriteria(Criteria.where("userId").in(userIds).and("taskId").is(taskId).and("activityId").is(activityId));
        List<UserActivityTaskRanking> userTaskRankingList = mongoTemplate.find(queryU, UserActivityTaskRanking.class);
        return userTaskRankingList;
    }

    @Override
    public UserActivityTaskRanking insert(UserActivityTaskRanking userActivityTaskRanking) {
        return repository.insert(userActivityTaskRanking);
    }

    @Override
    public void updateQuantityByActivityIdAndTaskIdAndUserId(String activityId, String taskId, String userId, Double quantity) {
        Update update = new Update();
        update.set("quantity", quantity);
        update.set("updatedTime", new Date());
        Query queryRank = new Query().addCriteria(Criteria.where("userId").is(userId).and("taskId").is(taskId).and("activityId").is(activityId));
        mongoTemplate.updateFirst(queryRank, update, UserActivityTaskRanking.class);
    }

    @Override
    public void updateById(UserActivityTaskRanking update) {
        log.error("updateById param:{}", JSON.toJSONString(update));
        Optional<UserActivityTaskRanking> optional = repository.findById(update.getId());
        if (!optional.isPresent()) {
            log.error("updateById  id is null id:{}", update.getId());
            return;
        }
        UserActivityTaskRanking userActivityTaskRanking = optional.get();
        if (update.getQuantity() != null) {
            userActivityTaskRanking.setQuantity(update.getQuantity());
        }
        if (update.getQuantityBack() != null) {
            userActivityTaskRanking.setQuantityBack(update.getQuantityBack());
        }
        if (StringUtils.isNotBlank(update.getProvince())) {
            userActivityTaskRanking.setProvince(update.getProvince());
        }
        if (StringUtils.isNotBlank(update.getProvinceBack())) {
            userActivityTaskRanking.setProvinceBack(update.getProvinceBack());
        }
        userActivityTaskRanking.setUpdatedTime(new Date());
        UserActivityTaskRanking save = repository.save(userActivityTaskRanking);
        log.error("updateById result:{}", JSON.toJSONString(save));
    }

    @Override
    public UserActivityTaskRanking findAndModify(Query query, Update update) {
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
        findAndModifyOptions.upsert(Boolean.TRUE);
        findAndModifyOptions.returnNew(Boolean.TRUE);
        return mongoTemplate.findAndModify(query, update, findAndModifyOptions, UserActivityTaskRanking.class);
    }

    @Override
    public List<UserActivityTaskRanking> getListFromDb(Query query, String activityId, Integer page, Integer pageSize) {
        log.info(":>>> 开始从数据库中查询排行榜:{},{},{},query:{},集合:{}", activityId, page, pageSize);
        Long startDb = System.currentTimeMillis();
        List<UserActivityTaskRanking> rankings = new ArrayList<>();

        String collectionName = mongoTemplate.getCollectionName(UserActivityTaskRanking.class);


        MongoCursor<Document> iterable = mongoTemplate.getCollection(collectionName).find(query.getQueryObject(), Document.class).limit(pageSize).skip((page - 1) * pageSize).noCursorTimeout(true).sort(query.getSortObject()).batchSize(pageSize).iterator();
        log.info(":>>> 活动:{} 游标耗时:{} 毫秒", activityId, System.currentTimeMillis() - startDb);
        while (iterable.hasNext()) {
            Document o = iterable.next();
            if (Objects.nonNull(o)) {
                UserActivityTaskRanking r = new UserActivityTaskRanking();
                if (StringUtils.isNotBlank(o.getString("id"))) {
                    r.setId(o.getString("id"));
                } else {
                    r.setId(o.getObjectId("_id").toString());
                }
                r.setName(o.getString("name"));
                r.setImageUrl(o.getString("imageUrl"));
                r.setQuantity(o.getDouble("quantity"));
                r.setUserId(o.getString("userId"));
                r.setActivityId(o.getString("activityId"));
                r.setCached(o.getBoolean("cached"));
                r.setCachedProvince(o.getBoolean("cachedProvince"));
                r.setTaskId(o.getString("taskId"));
                r.setUniversityId(o.getString("universityId"));
                r.setCreatedTime(o.getDate("createdTime"));
                r.setUpdatedTime(o.getDate("updatedTime"));
                r.setProvince(o.getString("province"));
                rankings.add(r);
            }
        }
        return rankings;
    }

    @Override
    public long updateByUserId(UserActivityTaskRanking userActivityTaskRanking) {
        Query query = new Query().addCriteria(Criteria.where("userId").is(userActivityTaskRanking.getUserId()));
        Update update = new Update();
        update.set("name", userActivityTaskRanking.getName());
        update.set("imageUrl", userActivityTaskRanking.getImageUrl());
        update.set("updatedTime", new Date());
        UpdateResult updateResult = mongoTemplate.updateMulti(query, update, UserActivityTaskRanking.class);
        return updateResult.getModifiedCount();
    }

    @Override
    public List<UserActivityTaskRanking> findByUserId(String userId) {
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId));
        List<UserActivityTaskRanking> userTaskRankingList = mongoTemplate.find(query, UserActivityTaskRanking.class);
        return userTaskRankingList;
    }
}
